package net.softwarefabrik.bde.core.model.platform;

import net.softwarefabrik.bde.core.model.BDEConstants;
import net.softwarefabrik.bde.core.model.BDEException;

/**
 * A value object which provides substancial information about a bundle.
 * 
 * @author Matthias Kuespert
 */
public final class BundleInfo implements Cloneable {

    private static final String CONFIG_SEPARATOR = ";";

    /**
     * The path to the bundle jar.
     */
    private String              path             = BDEConstants.EMPTY_STRING;

    /**
     * The (optional) path to the bundle source code.
     */
    private String              sourcePath       = BDEConstants.EMPTY_STRING;

    /**
     * The startlevel on which to load/start the bundle.
     */
    private int                 startLevel       = 0;

    /**
     * If true the bundle is started after install.
     */
    private boolean             doStart          = false;

    /**
     * Initializing constructor.
     * 
     * @param data The <code>String</code> to initialize from.
     * @throws BDEException if the given data is not valid
     */
    public BundleInfo(String data) throws BDEException {

        if (null == data) {
            return;
        }
        String[] parts = data.split(CONFIG_SEPARATOR);
        switch (parts.length) {
            case 4:
                this.sourcePath = parts[3];
            case 3:
                this.doStart = new Boolean(parts[2]).booleanValue();
            case 2:
                this.startLevel = new Integer(parts[1]).intValue();
            case 1:
                if (parts[0].length() > 0) {
                    this.path = parts[0];
                    break;
                } else {
                    throw new BDEException("BundleInfo data does not contain a path");
                }
            default:
                throw new BDEException("Could not parse BundleInfo data: " + data);
        }
    }

    /**
     * Initializing constructor.
     * 
     * 
     * @param path The path.
     * @param startLevel The start level.
     * @param doStart True if the bundleshould be started.
     * @param sourcePath The (optional) path to the sources.
     */
    public BundleInfo(String path, int startLevel, boolean doStart, String sourcePath) {
        this.path = path;
        this.startLevel = startLevel;
        this.doStart = doStart;
        this.sourcePath = sourcePath;
    }

    /**
     * @see Object.toString()
     * 
     * @return A <code>String</code> representation of this
     *         <code>BundleInfo</code> which can be parsed via the
     *         BundleInfo(String) constructor.
     */
    @Override
    public final String toString() {
        String result = getPath()
                        + CONFIG_SEPARATOR
                        + getStartLevel()
                        + CONFIG_SEPARATOR
                        + new Boolean(doStart()).toString()
                        + CONFIG_SEPARATOR
                        + getSourcePath();
        return result;
    }

    /**
     * @return A cloned object.
     */
    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            // TODO could this be ignored since we really do implement
            // Cloneable?
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @return the path
     */
    public final String getPath() {
        return path;
    }

    /**
     * @param path the path to set
     */
    public final void setPath(String path) {
        this.path = path;
    }

    /**
     * @return the startLevel
     */
    public final int getStartLevel() {
        return startLevel;
    }

    /**
     * @param startLevel the startLevel to set
     */
    public final void setStartLevel(int startLevel) {
        this.startLevel = startLevel;
    }

    /**
     * @return <code>true</code> if the bundle should be started
     *         automatically.
     */
    public final boolean doStart() {
        return doStart;
    }

    /**
     * @param doStart the doStart to set
     */
    public final void setDoStart(boolean doStart) {
        this.doStart = doStart;
    }

    /**
     * @return The source path.
     */
    public final String getSourcePath() {
        return sourcePath;
    }

    /**
     * @param sourcePath the sourcePath to set
     */
    public final void setSourcePath(String sourcePath) {
        this.sourcePath = sourcePath;
    }
}
